/////////////////////////////////////////////////////////////////////////////
// Original code from libhdfs3. Copyright (c) 2013 - 2014, Pivotal Inc.
// All rights reserved. Author: Zhanwei Wang
/////////////////////////////////////////////////////////////////////////////
//  Modifications by Kumo Inc.
/////////////////////////////////////////////////////////////////////////////
// Original code from libhdfs3. Copyright (c) 2013 - 2014, Pivotal Inc.
// All rights reserved. Author: Zhanwei Wang
/////////////////////////////////////////////////////////////////////////////
//  Modifications by Kumo Inc.
// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//




#pragma once


#include <kmhdfs/server/block_local_path_info.h>
#include <kmhdfs/client/token.h>
#include <kmhdfs/server/extended_block.h>
#include <kmhdfs/rpc/rpc_auth.h>
#include <kmhdfs/rpc/rpc_call.h>
#include <kmhdfs/rpc/rpc_client.h>
#include <kmhdfs/rpc/rpc_config.h>
#include <kmhdfs/rpc/rpc_protocol_info.h>
#include <kmhdfs/rpc/rpc_server_info.h>
#include <kmhdfs/common/session_config.h>

namespace Hdfs {
    namespace Internal {
        class Datanode {
        public:
            virtual ~Datanode() {
            }

            /**
             * Return the visible length of a replica.
             * @param b The block which visible length is to be returned.
             * @return the visible length of the block.
             * @throw ReplicaNotFoundException
             * @throw HdfsIOException
             */
            //Idempotent
            virtual int64_t getReplicaVisibleLength(const ExtendedBlock &b)
            /*throw (ReplicaNotFoundException, HdfsIOException)*/ = 0;

            /**
             * Retrieves the path names of the block file and metadata file stored on the
             * local file system.
             *
             * In order for this method to work, one of the following should be satisfied:
             * <ul>
             * <li>
             * The client user must be configured at the datanode to be able to use this
             * method.</li>
             * <li>
             * When security is enabled, kerberos authentication must be used to connect
             * to the datanode.</li>
             * </ul>
             *
             * @param block The specified block on the local datanode
             * @param token The block access token.
             * @param info Output the BlockLocalPathInfo of block.
             * @throw HdfsIOException
             */
            //Idempotent
            virtual void getBlockLocalPathInfo(const ExtendedBlock &block,
                                               const Token &token, BlockLocalPathInfo &info)
            /*throw (HdfsIOException)*/ = 0;
        };

        class DatanodeImpl : public Datanode {
        public:
            DatanodeImpl(const std::string &host, uint32_t port, const SessionConfig &c,
                         const RpcAuth &a);

            virtual int64_t getReplicaVisibleLength(const ExtendedBlock &b);

            virtual void getBlockLocalPathInfo(const ExtendedBlock &block,
                                               const Token &token, BlockLocalPathInfo &info);

        private:
            void invoke(const RpcCall &call, bool reuse);

        private:
            RpcAuth auth;
            RpcClient &client;
            RpcConfig conf;
            RpcProtocolInfo protocol;
            RpcServerInfo server;
        };
    }
}
